﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MathLib
{
    [Serializable]
    public class Vector
    {
        public double[] vectorArray;
        public int Dimension;

        public Vector(double[] Values)
        {
            vectorArray = Values;
            Dimension = vectorArray.GetLength(0);
        }

        public Vector(int dim)
        {
            vectorArray = new double[dim];
            Dimension = dim;
            Zero();
        }

        public Vector(int dim, double initValue)
        {
            vectorArray = new double[dim];
            Dimension = dim;
            for (int i = 0; i < Dimension; i++)
                vectorArray[i] = initValue;
        }

        public void Zero()
        {
            for (int i = 0; i < Dimension; i++)
            {
                vectorArray[i] = 0;
            }
        }

        public double Abs()
        {
            double abs = 0;

            for (int i = 0; i < Dimension; i++)
            {
                abs += vectorArray[i] * vectorArray[i];
            }
            return Math.Sqrt(abs);
        }

        public double Dot(Vector vector)
        {
            if (vector.Dimension != Dimension)
            {
                return 0;
            }
            double dotProd = 0;
            for (int i = 0; i < Dimension; i++)
            {
                dotProd += vectorArray[i] * vector.vectorArray[i];
            }
            return dotProd;
        }

        public double Cos(Vector vector)
        {
            if (vector.Dimension != Dimension)
                return 0;
            double result = 0;
            result = this.Dot(vector) / (this.Abs() * vector.Abs());
            return result;
        }


        public double Cos()
        {
            double init = 1.0 / Math.Sqrt(this.Dimension);
            Vector vector = new Vector(this.Dimension, init);
            double result = this.Dot(vector) / (this.Abs() * vector.Abs());
            return result;
        }

        public Vector Scale(double factor)
        {
            double[] values = new double[Dimension];

            for (int i = 0; i < Dimension; i++)
            {
                values[i] = vectorArray[i] * factor;
            }
            return new Vector(values);
        }

        public override string ToString()
        {
            string str = "";
            for (int i = 0; i < Dimension; i++)
            {
                if (i != 0)
                {
                    str += ",";
                }
                str += vectorArray[i];
            }
            return "(" + str + ")";
        }

        public static Vector FromString(String data)
        {
            data = data.Substring(1);
            data = data.Substring(0,data.Length - 1);
            String[] separator = new string[1];
            separator[0] = ",";
            String[] dataArray = data.Split(separator, StringSplitOptions.RemoveEmptyEntries);
            double[] values = new double[dataArray.Length];            
            for (int i = 0; i < dataArray.Length; i++)
			{
                values[i] = Double.Parse(dataArray[i]);
			}
            Vector result = new Vector(values);
            return result;
        }

        public static Vector operator +(Vector left, Vector right)
        {
            if (left.Dimension != right.Dimension)
            {
                return left;
            }
            double[] values = new double[left.Dimension];

            for (int i = 0; i < left.Dimension; i++)
            {
                values[i] = left.vectorArray[i] + right.vectorArray[i];
            }
            return (new Vector(values));
        }

        public static Vector operator -(Vector left, Vector right)
        {
            if (left.Dimension != right.Dimension)
            {
                return left;
            }
            double[] values = new double[left.Dimension];

            for (int i = 0; i < left.Dimension; i++)
            {
                values[i] = left.vectorArray[i] - right.vectorArray[i];
            }
            return (new Vector(values));
        }
    }
}  
